package nancal.mp.model

import com.fasterxml.jackson.annotation.JsonProperty
import nbcp.base.comm.JsonMap
import nbcp.base.enums.ApiParameterTypeEnum
import nbcp.base.extend.HasValue
import nbcp.base.extend.Slice
import nbcp.base.model.ApiBodyParameterDefine

class SwaggerSchemasPropertyItem {
    @JsonProperty("\$ref")
    var ref = "";

    var type = ""

    /**
     * 枚举项，这里可能是枚举的数组
     */
    var enum = mutableListOf<String>()
}

class SwaggerSchemasProperty {
    var type = "";
    var format = ""
    var description = "";

    @JsonProperty("\$ref")
    var ref = "";

    var items = SwaggerSchemasPropertyItem()

    /**
     * 枚举项
     */
    var enum = mutableListOf<String>()

    val properties: MutableMap<String, SwaggerSchemasProperty>
        get() {
            if (ref == "") {
                return mutableMapOf();
            }

            return SwaggerModel.swaggerInstance.getProperties(ref);
        }
}


fun Map.Entry<String, SwaggerSchemasProperty>.toParameterDefine(
    pTypes: List<String> = listOf(),
    depth: Int = 0
): ApiBodyParameterDefine {

    var ret = ApiBodyParameterDefine();
    if (depth > 8) {
        return ret;
    }

    ret.key = this.key;
    ret.remark = this.value.description
    ret.isList = this.value.type == "array"

    if (ret.isList == false) {
        if (this.value.ref.HasValue) {
            ret.type = ApiParameterTypeEnum.Object
        } else {
            ret.type = ApiParameterTypeEnum.loadWithSwaggerType(this.value.type);
        }
    } else {

        if (this.value.ref.HasValue) {
            ret.type = ApiParameterTypeEnum.Object;
        }
        if (this.value.items.ref.HasValue) {
            ret.type = ApiParameterTypeEnum.Object;

            if (this.value.items.ref.startsWith("#/")) {
                var embedTypeName = this.value.items.ref.split("/").last()

                if (pTypes.contains(embedTypeName)) {
                    return ApiBodyParameterDefine();
                }

                ret.referenceModelName = embedTypeName;
                var embedType =
                    SwaggerModel.swaggerInstance.models.get(embedTypeName)

                if (embedType != null) {
                    var lt = embedType.properties.map { it.toParameterDefine(pTypes + listOf(embedTypeName), depth + 1) }

                    ret.items.addAll(lt);
                }
            }
        }
        //简单类型的数组
        else {
            ret.type = ApiParameterTypeEnum.loadWithSwaggerType(this.value.items.type);
            if (this.value.items.type == "string" && this.value.items.enum.size > 0) {
                ret.type = ApiParameterTypeEnum.Enum
                ret.enumData = this.value.items.enum;
            }
        }
    }

    if (ret.type == ApiParameterTypeEnum.String && this.value.enum.size > 0) {
        ret.type = ApiParameterTypeEnum.Enum
        ret.enumData = this.value.enum;
    }


    if (ret.type == ApiParameterTypeEnum.Object && this.value.properties.any()) {
        if (pTypes.contains(this.value.ref)) {
            return ApiBodyParameterDefine();
        }


        ret.items.addAll(this.value.properties.map {
            it.toParameterDefine(pTypes, depth = depth + 1)
        })
    }
    return ret;
}

class SwaggerSchemasProperties {
    var properties = mutableMapOf<String, SwaggerSchemasProperty>();

    /**
     * 中文名，如： ApiResult«用户表 列表回发VO»， 一般 等于 父对象的key
     */
    var title = "";

    val isGenericType: Boolean
        get() {
            return this.title.endsWith("»") && this.title.contains("«")
        }

    fun getTypeName(): String {
        if (this.title.endsWith("»")) {
            var startIndex = this.title.indexOf("«");
            if (startIndex > 0) {
                return this.title.substring(0, startIndex);
            }
        }
        return "";
    }

    fun getRefTypeName(): String {
        if (this.title.endsWith("»")) {
            var startIndex = this.title.indexOf("«");
            if (startIndex > 0) {
                return this.title.Slice(startIndex + 1, -1);
            }
        }
        return "";
    }

}

class SwaggerComponents {
    /**
     * key = 对象类型， 但泛型会比较复杂。 如： ApiResult«用户表 列表回发VO»
     */
    var schemas = mutableMapOf<String, SwaggerSchemasProperties>()


}


class SwaggerRequestParameterDef {
    var `in` = ""
    var name = ""
    var description = "";
    var required = false
    var schema = JsonMap()
    var style = ""

}

class SwaggerRequestBodyContentJsonSchema {
    @JsonProperty("\$ref")
    var ref = "";
}

class SwaggerRequestBodyContentJson {
    var schema = SwaggerRequestBodyContentJsonSchema();
}

class SwaggerRequestBodyContent {
    @JsonProperty("application/json")
    var applicationJson = SwaggerRequestBodyContentJson();
}

class SwaggerRequestBody {
    var content = SwaggerRequestBodyContent();
}


//class SwaggerResponseAnySchema {
//
//    /**
//     * #/components/schemas/ApiResult«用户组关系表»
//     */
//    @JsonProperty("\$ref")
//    var ref = "";
//}

class SwaggerResponse {
    /**
     * 一般key是 星/星
     */
    var content: MutableMap<String, SwaggerRequestBodyContentJson>? = null
}

class SwaggerRequestDef {
    var tags = mutableListOf<String>()
    var parameters = mutableListOf<SwaggerRequestParameterDef>()
    var requestBody = SwaggerRequestBody()
    var responses = mutableMapOf<Int, SwaggerResponse>()
    var summary = ""
    var description = ""


    fun getRequestModelRef(): String {
        return this.requestBody.content.applicationJson.schema.ref;
    }

    fun getResponseModelRef(): String {
        if (responses.any() == false) {
            return ""
        }

        var response = responses.get(200);

        if (response == null) {
            return ""
        }


        if (response.content.isNullOrEmpty()) {
            return ""
        }

        var m = response.content!!.values.first();


        //#/components/schemas/ApiResult«用户组关系表»

        return m.schema.ref;
    }

}

class SwaggerPathObj {
    var get: SwaggerRequestDef? = null;
    var post: SwaggerRequestDef? = null;
    var put: SwaggerRequestDef? = null;
    var delete: SwaggerRequestDef? = null;
}

class SwaggerModel {
    var definitions = mutableMapOf<String, SwaggerSchemasProperties>();
    var components = SwaggerComponents();


    var paths = mutableMapOf<String, SwaggerPathObj>();

    val models: Map<String, SwaggerSchemasProperties>
        get() {
            if (definitions.any()) {
                return definitions
            }
            return components.schemas;
        }


    fun getProperties(fullName: String): MutableMap<String, SwaggerSchemasProperty> {
        var name = fullName.split("/").last()

        var properties = models.get(name);
        if (properties == null) {
            return mutableMapOf();
        }

        return properties.properties;
    }

    /**
     * /mnt/app/code/nancal/mp/mp-api/api/admin-api/kotlin/nancal/mp/mvc/dev/ApiDefineController.kt
     * toItem方法
     */
    fun getModel(fullName: String): ApiBodyParameterDefine {
        var ret = ApiBodyParameterDefine()

        var lt = getProperties(fullName).map { it.toParameterDefine() };
        ret.items.addAll(lt)

        return ret;
    }

    companion object {
        var swaggerInstance = SwaggerModel();
    }
}

